<template>
  <div class="app-message-custom">
    <div title="新的通知" class="bell" @click="() => {showPopper = !showPopper}">
      <v-badge :overlap="true" :content="messagelist.length" :value="messagelist.length">
        <v-icon v-show="messagelist.length > 0" class="bell-icon" :dense="true">fa fa-bell-o</v-icon>
        <v-icon v-show="messagelist.length <= 0" :dense="true">fa fa-bell-o</v-icon>
      </v-badge>
    </div>
    <div class="popover" v-if="showPopper">
      <header>
        <h3>通知</h3>
      </header>
      <div class="list-warpper">
        <div class="pop-empty" v-show="messagelist.length <= 0">
          <span>- 没有新通知 -</span>
        </div>
        <transition-group name="fade" tag="div">
          <div class="item" v-for="item in messagelist" :key="item.id">
            <header>
              <h6 class="item-title">
                <span class="item-link">
                  <v-icon :dense="true">fa-square-o</v-icon>
                  <span>{{ item.content }}</span>
                </span>
              </h6>
              <div class="action" @click="removeItem(item)">
                <v-icon>el-icon-check</v-icon>
              </div>
            </header>
            <div class="informgroup">
              <div class="informgroup-item">
                <div :class="user.personname ? 'headportrait '+$util.getColorByPersonName(user.personname) : 'headportrait '+$util.getColorByPersonName(user.loginname)">
                  <span class="headportrait-text">{{ user.personname ? user.personname.substring(user.personname.length - 1) : user.loginname.substring(user.loginname.length - 1) }}</span>
                </div>
                <div class="messagecontent">
                  <b>张三</b>
                  <span>将任务完成时间从没有截止时间修改为11月05日</span>
                </div>
              </div>
              <div class="informgroup-item">
                <div :class="user.personname ? 'headportrait '+$util.getColorByPersonName(user.personname) : 'headportrait '+$util.getColorByPersonName(user.loginname)">
                  <span class="headportrait-text">{{ user.personname ? user.personname.substring(user.personname.length - 1) : user.loginname.substring(user.loginname.length - 1) }}</span>
                </div>
                <div class="messagecontent">
                  <b>张三</b>
                  <span>回复：@某人 麻烦赶紧处理下</span>
                </div>
              </div>
            </div>
          </div>
        </transition-group>
        <!-- <span>加载更多...</span> -->
      </div>
      <div class="fotter">
        <span>查看全部通知</span>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import {
  Vue,
  Component,
  Prop,
  Model,
  Emit,
  Watch,
  Provide,
} from "vue-property-decorator";

import "./app-message-custom.less";

@Component({})
export default class AppMessageCustom extends Vue {
  /**
   * 重新连接设置对象
   *
   * @type {*}
   * @memberof AppMessageCustom
   */
  public heartCheck: any = {
    timeout: 50000,
    timeoutObj: null,
    serverTimeoutObj: null,
  };

  /**
   * 信息集合
   *
   * @type {Array<*>}
   * @memberof AppMessageCustom
   */
  public messagelist: Array<any> = [
    { id: this.$util.createUUID(), content: "111. 某某某任务" },
  ];

  /**
   * webSocket对象
   *
   * @type {*}
   * @memberof AppMessageCustom
   */
  public socket: any = {};

  /**
   * webSocket状态
   *
   * @type {*}
   * @memberof AppMessageCustom
   */
  public socketState: any;

  /**
   * 避免重连判断
   *
   * @type {boolean}
   * @memberof AppMessageCustom
   */
  public lockReconect: boolean = false;

  /**
   * 心跳定时器
   *
   *
   * @type {*}
   * @memberof AppMessageCustom
   */
  public timer: any;

  /**
   * 用户对象
   * 
   * @type {*}
   */
  public user: any;

  /**
   * 重置定时服务
   *
   * @memberof AppMessageCustom
   */
  public reset() {
    clearTimeout(this.heartCheck.timeoutObj);
    clearTimeout(this.heartCheck.serverTimeoutObj);
    this.start();
  }

  /**
   * 删除通知消息
   *
   * @param {*} [item] 当前通知消息对象
   * @memberof AppMessage
   */
  public removeItem(item: any) {
    let that: any = this;
    for (let i = 0; i < this.messagelist.length; i++) {
      if (Object.is(this.messagelist[i].id, item.id)) {
        that.messagelist.splice(i, 1);
        break;
      }
    }
  }

  /**
   * 心跳开始
   *
   * @memberof AppMessageCustom
   */
  public start() {
    if (this.socket && this.socket.readyState === 1) {
      this.heartCheck.timeoutObj = setTimeout(() => {
        this.socket.send("ping");
      }, this.heartCheck.timeout);
    }
  }

  /**
   * 连接webSocket
   *
   * @memberof AppMessageCustom
   */
  public linkSocket() {
    this.socket = new WebSocket("ws://localhost:8080/inform/" + this.user.loginname);
    this.initEventHandle();
  }

  /**
   * 初始化webSocket
   *
   * @memberof AppMessageCustom
   */
  public initEventHandle() {
    let that: any = this;
    this.socket.onopen = () => {
      that.reset();
    };
    this.socket.onmessage = (res: any) => {
      if (res.data == "pong") {
        that.reset();
        console.log("心跳");
      } else {
        //console.log("messageinfo");
      }
    };
    this.socket.onerror = () => {
      console.log("WebSocket连接打开失败");
      if (that.socketState) {
        that.reconnect(that.socketUrl);
      }
    };
    this.socket.onclose = () => {
      console.log("WebSocket 已关闭！");
      if (that.socketState) {
        that.reconnect(that.socketUrl);
      }
    };
  }

  /**
   * socket重连
   *
   * @memberof AppMessageCustom
   */
  public reconnect() {
    console.log("重新连接");
    if (this.lockReconect) return;
    this.lockReconect = true;
    clearTimeout(this.timer);
    this.timer = setTimeout(() => {
      this.linkSocket();
      this.lockReconect = false;
    }, 5000);
  }

  /**
   * 通知框显示状态
   *
   * @memberof AppMessageCustom
   */
  public showPopper: boolean = false;

  /**
   * vue生命周期
   *
   * @memberof AppMessageCustom
   */
  public mounted() {
    let that: any = this;
    let win: any = window;
    let user: any = JSON.parse(win.localStorage.getItem("user"));
    document.addEventListener("click", function (e: any) {
      // 下面这句代码是获取 点击的区域是否包含你的菜单，如果包含，说明点击的是菜单以外，不包含则为菜单以内
      let flag = e.target.contains(
        document.getElementsByClassName("popover")[0]
      );
      console.log(flag);
      if (!flag) return;
      that.showPopper = false;
    });
    if (user) {
      this.user = user;
      this.linkSocket();
    }
  }

  /**
   * vue生命周期组件销毁后
   *
   * @memberof AppMessageCustom
   */
  public beforeDestroy() {
    if (this.socket) {
      this.socket.close();
    }
  }
}
</script>
